package driver.android.http;

import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import android.widget.ImageView;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import driver.util.IHttpCallBack;
import driver.util.Util;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/*
 * okHttp3的封装
 */
public class CommonOkHttpClient {

    private volatile static CommonOkHttpClient mInstance;
    private OkHttpClient mOkHttpClient;
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    private static IHttpCallBack mIHttpCallBack;

    private CommonOkHttpClient() {
        OkHttpClient.Builder clientBuilder = new OkHttpClient().newBuilder();
        clientBuilder.readTimeout(30, TimeUnit.SECONDS);
        clientBuilder.connectTimeout(15, TimeUnit.SECONDS);
        clientBuilder.writeTimeout(30, TimeUnit.SECONDS);
//        clientBuilder.addInterceptor(new TokenInterceptor());
        mOkHttpClient = clientBuilder.build();
    }

    public static CommonOkHttpClient getInstance(IHttpCallBack callback) {
        CommonOkHttpClient temp = mInstance;
        mIHttpCallBack = callback;
        if (temp == null) {
            synchronized (CommonOkHttpClient.class) {
                temp = mInstance;
                if (temp == null) {
                    temp = new CommonOkHttpClient();
                    mInstance = temp;
                }
            }
        }
        return temp;
    }

    /**
     * 设置请求头
     */
    private Headers SetHeaders(Map<String, String> headersParams) {
        Headers headers;
        Headers.Builder headersBuilder = new Headers.Builder();
        if (headersParams != null) {
            Iterator<String> iterator = headersParams.keySet().iterator();
            String key = "";
            while (iterator.hasNext()) {
                key = iterator.next();
                headersBuilder.add(key, headersParams.get(key));
            }
        }
        headers = headersBuilder.build();
        return headers;
    }

    /**
     * post请求参数
     */
    private RequestBody SetPostRequestBody(Map<String, String> BodyParams) {
        RequestBody body;
        FormBody.Builder formEncodingBuilder = new FormBody.Builder();
        if (BodyParams != null) {
            Iterator<String> iterator = BodyParams.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                String value = BodyParams.get(key);
                if (!TextUtils.isEmpty(value)) {
                    formEncodingBuilder.add(key, value);
                }
            }
        }
        body = formEncodingBuilder.build();
        return body;
    }

    /**
     * put请求
     */
    public void doPut(String reqUrl, Map<String, String> headersParams, Map<String, String> params) {
        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(reqUrl);
        RequestBuilder.method("PUT", SetPostRequestBody(params));
        RequestBuilder.headers(SetHeaders(headersParams));
        Request request = RequestBuilder.build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                Util.debugApp('d', "mOkHttpClient onResponse " + response.code());
                int code = response.code();
                if (code == 200) {
                    mIHttpCallBack.success(response);
                } else {
                    mIHttpCallBack.codeInvalid(response);
                }
                call.cancel();
            }

            @Override
            public void onFailure(final Call call, final IOException exception) {
                mIHttpCallBack.fail(exception);
                call.cancel();
            }
        });
    }

    private String getReqUrlName(String url) {
        int position = url.lastIndexOf("/");
        String type = url.substring(position + 1, url.length());
        Util.debugApp('d', "发送HTTP请求的地址截取 " + type);
        return type;
    }

    /**
     * 上传图片
     */
    private RequestBody SetFileRequestBody(Map<String, String> BodyParams, Map<String, String> filePathParams) {
        RequestBody body;
        MultipartBody.Builder MultipartBodyBuilder = new MultipartBody.Builder();
        MultipartBodyBuilder.setType(MultipartBody.FORM);
        RequestBody fileBody;
        if (BodyParams != null) {
            Iterator<String> iterator = BodyParams.keySet().iterator();
            String key;
            while (iterator.hasNext()) {
                key = iterator.next();
                MultipartBodyBuilder.addFormDataPart(key, BodyParams.get(key));
            }
        }
        if (filePathParams != null) {
            Iterator<String> iterator = filePathParams.keySet().iterator();
            String key = "";
            int i = 0;
            while (iterator.hasNext()) {
                key = iterator.next().toString();
                i++;
                Util.debugApp('d', "AAB mOkHttpClient发送的文件key " + key + " 路径 " + filePathParams.get(key));
                fileBody = RequestBody.create(MEDIA_TYPE_PNG, new File(filePathParams.get(key)));
                MultipartBodyBuilder.addFormDataPart("driver_conf_img", i + ".png", fileBody);
            }
        }
        body = MultipartBodyBuilder.build();
        return body;
    }

    /**
     * get方法连接拼加参数,该方法只支持一个参数
     */
    private String setGetUrlParams(Map<String, String> mapParams) {
        String strParams = "";
        if (mapParams != null) {
            Iterator<String> iterator = mapParams.keySet().iterator();
            String key = "";
            while (iterator.hasNext()) {
                key = iterator.next().toString();
                strParams += "?" + key + "=" + mapParams.get(key);
            }
        }
        return strParams;
    }

    /**
     * post请求
     */
    public void doPost(String reqUrl, Map<String, String> headersParams, Map<String, String> params) {
        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(reqUrl);
        RequestBuilder.method("POST", SetPostRequestBody(params));
        RequestBuilder.headers(SetHeaders(headersParams));
        Request request = RequestBuilder.build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                Util.debugApp('d', "mOkHttpClient onResponse " + response.code());
                int code = response.code();
                if (code == 200) {
                    mIHttpCallBack.success(response);
                } else {
                    mIHttpCallBack.codeInvalid(response);
                }
                call.cancel();
            }

            @Override
            public void onFailure(final Call call, final IOException exception) {
                mIHttpCallBack.fail(exception);
                call.cancel();
            }
        });
    }

    /**
     * post请求
     */
    public void doPostWithFile(String reqUrl, Map<String, String> headersParams, Map<String, String> BodyParams, Map<String, String> filePathParams) {
        Util.debugApp('d', "mOkHttpClient requestBody reqUrl " + reqUrl);
        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(reqUrl);
        RequestBody requestBody = SetFileRequestBody(BodyParams, filePathParams);
        RequestBuilder.method("POST", requestBody);
        RequestBuilder.headers(SetHeaders(headersParams));
        Request request = RequestBuilder.build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                Util.debugApp('d', "AAB mOkHttpClient doPostWithFile " + response.code());
                int code = response.code();
                if (code == 200) {
                    mIHttpCallBack.success(response);
                } else {
                    mIHttpCallBack.codeInvalid(response);
                }
                call.cancel();
            }

            @Override
            public void onFailure(final Call call, final IOException exception) {
                mIHttpCallBack.fail(exception);
                call.cancel();
            }
        });
    }


    /**
     * get请求
     */
    public void doGet(String reqUrl, Map<String, String> headersParams, Map<String, String> params) {
        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(reqUrl + setGetUrlParams(params));
        RequestBuilder.headers(SetHeaders(headersParams));
        Request request = RequestBuilder.build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                Util.debugApp('d', "mOkHttpClient onResponse " + response.code());
                int code = response.code();
                if (code == 200) {
                    mIHttpCallBack.success(response);
                } else {
                    mIHttpCallBack.codeInvalid(response);
                }
                call.cancel();
            }

            @Override
            public void onFailure(final Call call, final IOException exception) {
                mIHttpCallBack.fail(exception);
                call.cancel();
            }
        });
    }

    /**
     * 实现加载图片
     */
    public void loadImage(final Context context, final String reqUrl, Map<String, String> headersParams, final ImageView imageView, final String defResImag) {
        Bitmap result;
        // 从内存缓存中获取图片
        final ImageMemoryCache memoryCache = new ImageMemoryCache(context);
        result = memoryCache.getBitmapFromCache(reqUrl);
        if (result != null) {
            imageView.setImageBitmap(result);
            return;
        }
        // 从硬盘缓存中获取图片
        final ImageFileCache fileCache = new ImageFileCache(context);
        result = fileCache.getImage(context, reqUrl);
        if (result != null) {
            imageView.setImageBitmap(result);
            // 添加到内存缓存
            memoryCache.addBitmapToCache(reqUrl, result);
            return;
        }
        Request.Builder RequestBuilder = new Request.Builder();
        RequestBuilder.url(reqUrl);// 添加URL地址
        // RequestBuilder.headers(SetHeaders(headersParams));// 添加请求头
        Request request = RequestBuilder.build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
            }

            @Override
            public void onFailure(final Call call, final IOException exception) {
            }
        });
    }
}
